\chapter{Implementace}

V následující kapitole budu popisovat implementovanou architekturu aplikace. U složitějších algoritmů se pozastavím a blíže popíši danou problematiku.

\section{Výběr nástrojů}

Aplikace je vyvinuta na platformě Microsoft .NET verze 4.0 s využitím technologie \textbf{WPF} (viz kapitola \ref{sec:wpf}). Jako programovací jazyk byl zvolen C\#. Technologie \textbf{WPF} byla zvolena proto, že umožňuje snadno oddělovat aplikační vrstvu s vrstvou prezenční. Toto oddělení bylo navíc podpořeno doporučeným návrhovým vzorem M-V-VM (viz kapitola \ref{sec:mvvm}). Pro snazší implementaci byl použit jednoduchý framework \textbf{Caliburn.Micro} (viz kapitola \ref{sec:cm}) a pro snazší dekompozici je podpořen dalším frameworkem \textbf{MEF} (viz kapitola \ref{sec:mef}). 

Výhodou všech těchto technik, technologií a frameworků je to, že umí spolu úzce spolupracovat a po jejich pochopení usnadňují vývojáři mnoho práce a také udržují kód přehledný, čímž je splněn požadavek na rozšiřitelnost a znuvupoužitelnost aplikace.

Pro samotný vývoj byly využity tyto nástroje:

\begin{itemize}
	\item Microsoft Visual Studio 2010
	\item Microsoft SQL Server Management Studio (v. 10.50.1617.0)
	\item .NET framework 4.0
\end{itemize}

Dále byly využity tyto knihovny třetích stran:

\begin{itemize}
	\item Helix 3D Toolkit - snazší manipulace s 3D objekty \cite{helix}
	\item log4net - pomocná knihovna pro logování \cite{log4net}
\end{itemize}

Nároky samotné aplikace nejsou vyšší než nároky na operační systém Windows s nainstalovaným .NET frameworkem 4.0.

\section{Struktura aplikace}

Aplikace je rozdělena do 4 samostatných částí. Každá je vytvořena v úplně oddělené sestavě (angl. assembly).

\begin{itemize}
	\item PanelComposer.Interfaces
	\item PanelComposer.Models
	\item PanelComposer.ViewModels
	\item PanelComposer.Views
\end{itemize}

\subsection{Interfaces}

Knihovna \textit{Interfaces} obsahuje sdílené rozhraní a výčet obrazovek (viz obr. \ref{fig:interfaces}). Tato knihovna je sdílena mezi zbylými třemi knihovnami. 

\begin{figure}[h!tb]
\begin{center}
\includegraphics[width=0.50\textwidth]{img/interfaces}
\end{center}
\caption{Obsah knihovny Interfaces}
\label{fig:interfaces}
\end{figure}

\newpage{}

\subsection{Models}

Knihovna \textit{Models} (viz obr. \ref{fig:models}) umožňuje komunikaci s lokální databází a obsahuje implementaci rozhraní \textbf{IRepository}. \textbf{Repository} je návrhový vzor, který sjednocuje přístup k různým entitám v databázi. Tato implementace je generická, lze ji tedy používat pro všechny entity stejně. Rozhraní \textbf{IRepository} obsahuje CRUD operace nad databází. 

Samotná databáze se nachází ve složce data. Jedná se o lokální databázi MS SQL Compact Edition, kterou lze používat jako snadné uložiště dat. K~samotné databázi pak aplikace přistupuje pomocí \textbf{LINQ2SQL} (viz kapitola \ref{sec:linq}). Protože Visual Studio 2010 neumí vytvořit datový model, tzv. \textit{DataClasses}, je nutné tento model generovat pomocí utility \textit{sqlmetal}. Bližší popis, jak na to, je rozepsán v textovém souboru \textbf{HowTo}.

\begin{figure}[h!tb]
\begin{center}
\includegraphics[width=0.50\textwidth]{img/models}
\end{center}
\caption{Obsah knihovny Models}
\label{fig:models}
\end{figure}

\newpage{}

\subsection{ViewModels}

Poslední knihovna \textit{ViewModels} (viz obr. \ref{fig:viewmodels}) je vrstvou aplikační. Úzce spolupracuje s \textit{Model}em a zpracovává data z databáze. Zaroveň s těmito daty manipuluje a poskytuje je vrstvě \textit{View}. Každá třída, která komunikuje s prezenční vrstvou aplikace končí v názvu postfixem \textbf{ViewModel}, dále je třeba, aby tyto třídy implementovaly rozhraní \textbf{INotifyPropertyChanged}. Tím docílíme toho, že jakákoliv změna vlastností na \textit{ViewModelu} bude dopropagována na \textit{View}. \textit{ViewModel} obsahuje 4 složky. 

\subsubsection{Shell}
Ve složce \textit{Shell} se nachází implementace ViewModelu pro okna aplikace. Toto okno je zodpovědné za navigaci po ostatních stránkách a ovládá samotné menu. Každá stránka je odděděna od třídy \textbf{NavigateScreen} a obsahuje název z výčtu \textbf{PageNames}. Tímto lze snadno identifikovat každou stránku a požádat hlavní okno (shell) o její zobrazení. Taková událost (jako je změna aktivní stránky) může být zajímavá i pro ostatní stránky. Samotná změna je vyvolána využitím tzv. \textit{EventAggregatoru}, který zajistí to, že všechny stránky, které jsou v něm registrovány a implementují rozhraní \textbf{IHandle<T>} daného typu událostí, tak budou při změně informováni.

\subsubsection{Pages}
Jak již bylo zmíněno v předchozích odstavcích, všechny stránky jsou uloženy ve složce \textit{Pages}. Každý ViewModel reprezentuje aplikační vrstvu pro jednu stránku. Zde je zejména nutné dodržet jmennou konvenci, tedy název odpovídá názvu \textbf{UserControl}u na View akorát s postfixem \textbf{ViewModel}.

\subsubsection{Events}
Pro veškeré události, které lze vyvolat přes \textit{EventAggregator} je nutné vytvořit objekt. Tento objekt nemusí obsahovat nic, ale pokud potřebujeme předat nějakou informaci, tak se nám toto velice hodí. Události jsou využity vždy, pokud je potřeba informovat více nezávislých zdrojů najednou.

\subsubsection{Core}
Tato složka obsahuje důležité třídy, které je vhodné oddělit od ViewModelu, například, protože stejnou funkci využívá více tříd (např. práce se soubory na disku). Třída \textbf{ClippingEar} obsahuje implementaci triangulaci obecného polygonu, konkrétně jde o implementaci algoritmu ořezávání ,,uší''.

Tento algoritmus pracuje tak, že nejprve seřadí jednotlivé vrcholy v protisměru hodinových ručiček. Další postup je, že vezme 3 vrcholy a kontroluje, jestli prostřední z nich je natočen na pravou či levou stranu. Pokud je na straně levé, lze tento vrchol prohlásit za ,,ucho“ a to uříznout jej, viz ukázka kódu (\ref{lst:cutear}).

% pridat ukazku algoritmu
\lstset{
	caption=Ukázka algoritmu ořezávání uší,
	label={lst:cutear}
  language = c,
	breaklines=true,
  showspaces = false,
  showstringspaces=false,
  showtabs = false,
  basicstyle = \ttfamily\footnotesize,
	tabsize=2,
	frame=single
	}
\begin{lstlisting}
/// <summary>
/// Triangulates the specified points.
/// </summary>
/// <param name="points">The points.</param>
public static IList<IList<Point>> Triangulate(IList<Point> points)
{
    // zdrojovy seznam bodu
    IList<Point> source = null;
    // seznam seznamu bodu
    IList<IList<Point>> result = new List<IList<Point>>();
    source = MakeClockOtherwise(points);
    int x = 0;
    // odrezavame usi, dokud nam nezbyde jeden trojuhelnik
    while (source.Count > 3)
    {
        // vytazeni bodu
        Point p0 = source[(x - 1 + source.Count) % source.Count];
        Point p1 = source[(x) % source.Count];
        Point p2 = source[(x + 1) % source.Count];
        // zkontrolujeme, zdali P1 je nalevo nebo napravo
        if (IsLeft(p0, p2, p1) < 0)
        {
            // pokud je vlevo, je treba zkontroloval zdali trojuhelnik neprochazi zkrz existujici hrany
            bool isOk = true;
            // projedeme vsechny body a budeme kontrolovat, zdali se nachazi uvnitr noveho trojuhelniku
            foreach (Point p in source)
            {
                // pouzite body automaticky preskocime
                if (p == p0 || p == p1 || p == p2) continue;
                // pokud je uvnitr, nastavime flaf isOk na false
                if (IsInsideTriangle(p0, p1, p2, p)) isOk = false;
            }
            // pokud je vse v poradku, tak vygenerujeme trojuhelnik
            if (isOk)
            {
                result.Add(new List<Point>() { p0, p1, p2 });
                source.Remove(p1);
            }
        }
        x++;
    }
    result.Add(source);
    return result;
}
\end{lstlisting}


\textbf{FileHelper} usnadňuje práci s ukládáním obrázků do složky \textit{Drawing} v kořenovém adresáři aplikace, vše ukládá pod kódovými názvy a vytváří záznam v databázi. \textbf{NavigateScreen} a \textbf{ValidatingScreen} jsou dvě rozšíření třídy \textit{Screen} z frameworku Caliburn.Micro. Tyto dvě třídy implementují vše potřebné pro každou stránku a umožňují snadné volání navigace a \textbf{ValidatingScreen} navíc obsahuje validace jednotlivých vlastností třídy, což je hojně využíváno u zakládacích či editačních obrazovek. Třída \textbf{Utils} obsahuje pomocné metody pro převod plátna na obrázek PNG.

Nejdůležitější třídou jádra je \textbf{Polygon3DModel}, který na základě předaných bodů polygonu, výšky a cesty k obrázku vygeneruje kompletní 3D model panelového domu.

\newpage{}

\begin{figure}[h!tb]
\begin{center}
\includegraphics[width=0.50\textwidth]{img/viewmodels}
\end{center}
\caption{Obsah knihovny ViewModels}
\label{fig:viewmodels}
\end{figure}

\newpage{}

\subsection{Views}

Samotná aplikace je spouštěna z assembly \textit{Views} (viz obr. \ref{fig:views}). Ta je tedy vstupním bodem aplikace a zároveň prezenční vrstvou. Nejdůležitější třídou \textbf{View} je jednoznačně \textbf{AppBootstrapper}, který je vyvolán hned po startu aplikace a za běhu propojuje jednotlivé \textit{assembly}, dále prohledává všechny třídy, které obsahují atribut \textit{Export} a všechny je načte do slovníku. Tento průzkum provede ještě jednou a pokusí se naopak vyhledat všechny objekty, které obsahují atribut \textit{Import}. Vnitřně si vybuduje strom závislostí, a jakmile si vyžádáme instanci některého z těchto zaregistrovaných objektů, tak automaticky inicializuje vše potřebné za nás. Toto je práce frameworku \textbf{MEF} (viz kapitola \ref{sec:mef}). 

Na druhou stranu, bootstrapper je objektem druhého frameworku \textbf{Caliburn.Micro} (viz kapitola \ref{sec:cm}), který naopak využije vlastností předchozího frameworku a vyžádá si vytvoření instance rozhraní \textbf{IShell}, který reprezentuje okno aplikace. O samotné propojení \textit{View} s \textit{ViewModelem} se postará úplně sám.

Neméně důležitý je také soubor \textbf{app.config}, který obsahuje konfiguraci logovací knihovny \textbf{Log4NET} a nastavení spojení s databází.

\subsubsection{Shells}
Tato složka obsahuje obdobně jako u \textit{ViewModelu} reprezentaci hlavního okna. Tentokrát ale nejde o aplikační vrstvu, ale o vrstvu prezenční. Třída \textbf{ShellView} tedy obsahuje design hlavní stránky.

\subsubsection{Pages}
Analogicky jako u předchozího odstavce, složka \textit{Pages} obsahuje design jednotlivých stránek.

\subsubsection{Themes}
Tato složka obsahuje tzv. \textbf{ResourcesDictionary}. Tento soubor obsahuje obecné styly, které jsou používány v celé prezenční vrstvě.

\subsubsection{UserControls}
Tato složka obsahuje specifické uživatelské kontrolky, které jsou výrazně pozměněny oproti jejím standardním implementacím. Zde jsou konkrétně umístěny dvě kontrolky. \textbf{BaseCanvas} je kreslící plátno speciálně upravené tak, aby vyhovovalo kreslení půdorysu panelových domů. Tedy umožňuje kreslení polygonu.

\textbf{PanelCanvas} je opět upravené kreslící plátno, které ale tentokrát na základě vstupních dat generuje výslednou texturu 3D modelu.

\subsubsection{Logging}
Tato složka obsahuje implementaci rozhraní \textbf{ILog} od frameworku \textbf{CM} a propojuje funkcionalitu tohoto frameworku s logovací knihovnou \textbf{Log4NET}.

\newpage{}

\begin{figure}[h!tb]
\begin{center}
\includegraphics[width=0.50\textwidth]{img/views}
\end{center}
\caption{Obsah knihovny Views}
\label{fig:views}
\end{figure}

\newpage{}

\section{Navigace a databáze}

Následující obrázek \ref{fig:screenflow} popisuje možný průchod aplikací. Tedy odkud kam se lze dostat z dané stránky. Tato navigace se obecně nazývá \textbf{Screen Flow}. Databázové schéma \ref{fig:db_simple} popisuje jednotlivé entity v databázi a vztahy mezi nimi. Lze tedy snadno vypozorovat, že každý \textit{Solution} může obsahovat 0 až N projektů a s každým tímto projektem lze samostatně manipulovat. Toto popisuje vazební tabulka \textit{SolutionProject}. 

\begin{figure}[h!tb]
\begin{center}
\includegraphics[width=1\textwidth]{img/screenflow}
\end{center}
\caption{Obsah knihovny Views}
\label{fig:screenflow}
\end{figure}

\begin{figure}[h!tb]
\begin{center}
\includegraphics[width=1\textwidth]{img/db_simple}
\end{center}
\caption{Databázové schéma}
\label{fig:db_simple}
\end{figure}